home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / PCI Driver Development Kit / • Samples / Driver Samples / Video samples / GDX 950717 / GDX / GraphicsCore.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-20  |  31.1 KB  |  958 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        GraphicsCore.c
  3.  
  4.     Contains:    This file implements the Intialize, Open, Close, Status, Control, and Finalize
  5.                 routines, as well as come other 'core' related functions.
  6.  
  7.     Written by:    Sean Williams, Kevin Williams
  8.  
  9.     Copyright:    © 1994-1995 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>     7/17/95    SW        In Graphics Open(), now apply the default gamma table instead of
  14.                                      a linear one.  Also, do some slight changes to better support
  15.                                     drivers which don't fully support kReplace/Supercede commands to
  16.                                     eliminate the CLUT being incorrectly grayed out.
  17.          <1>     4/15/95    SW        First Checked In
  18.  
  19. */
  20.  
  21. #include "GraphicsPriv.h"
  22. #include "GraphicsCore.h"
  23. #include "GraphicsCorePriv.h"
  24. #include "GraphicsCoreControl.h"
  25. #include "GraphicsCoreStatus.h"
  26. #include "GraphicsCoreUtils.h"
  27. #include "GraphicsHAL.h"
  28. #include "GraphicsOSS.h"
  29.  
  30. #include <Devices.h>
  31. #include <DriverServices.h>
  32. #include <NameRegistry.h>
  33. #include <Errors.h>
  34. #include <Video.h>
  35.  
  36.  
  37. typedef    struct CoreReplacementDriverInfo CoreReplacementDriverInfo;
  38. struct CoreReplacementDriverInfo 
  39. {
  40.     DisplayModeID displayModeID;    // Current display mode selector
  41.     DepthMode depthMode;            // Relative bit depth
  42.     short currentPage;                // Current graphics page (0 based)
  43.     void *baseAddress;                // Base address of current page of frame buffer
  44. };
  45.  
  46.  
  47. // Forward delcarations of GraphicsCore.c routines that nobody else has to know about
  48. static GDXErr GraphicsCoreInitPrivateData(DriverRefNum refNum, const RegEntryID* regEntryID,
  49.             const AddressSpaceID spaceID);
  50.  
  51. void GraphicsCoreKillPrivateData(void);
  52.  
  53.  
  54. GraphicsCoreData gCoreData;                // Persistant globals for the Core's private data.
  55.  
  56.  
  57.  
  58. //=====================================================================================================
  59. //
  60. // GraphicsCoreGetCoreData()
  61. //    This the access method for the Core's private data.  ALWAYS uses this function to obtain
  62. //    a pointer to the private data, as opposed to trying to access the data directly.
  63. //    You have been warned...
  64. //
  65. //=====================================================================================================
  66. GraphicsCoreData *GraphicsCoreGetCoreData(void)
  67. {
  68.     return &gCoreData;
  69. }
  70.  
  71.  
  72.  
  73. //=====================================================================================================
  74. //
  75. // GraphicsCoreInitPrivateData()
  76. //
  77. //    This routine initializes the Core's private data to its proper state.
  78. //
  79. //=====================================================================================================
  80. static GDXErr GraphicsCoreInitPrivateData(DriverRefNum refNum, const RegEntryID *regEntryID, const AddressSpaceID spaceID)
  81. {
  82.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  83.     GDXErr err = kGDXErrNoError;                                                    // Assume success
  84.     DisplayModeIDData *masterTable = (DisplayModeIDData *) &coreData->masterTable;
  85.     UInt32 i;                                                                        // Loop iterator
  86.  
  87.     DisplayModeIDData localTable[kMaxDisplayModeIDs] =
  88.     {
  89.         {kDisplay512x384At60HzNTSC,        512, 384, 0x003BF080},        // 59.94 Hz
  90.         {kDisplay512x384At60Hz,            512, 384, 0x003C0000},        // 60 Hz
  91.         {kDisplay640x480At50HzPAL,        640, 480, 0x00320000},        // 50 Hz
  92.         {kDisplay640x480At60HzNTSC,        640, 480, 0x003BF080},        // 59.94 Hz
  93.         {kDisplay640x480At60HzVGA,        640, 480, 0x003BF080},        // 59.94 Hz
  94.         {kDisplay640x480At67Hz,            640, 480, 0x0042AA80},        // 66.67 Hz
  95.  
  96.         {kDisplay640x870At75Hz,            640, 870, 0x004B0000},        // 75 Hz
  97.  
  98.         {kDisplay768x576At50HzPAL,        768, 576, 0x00320000},        // 50 Hz
  99.         {kDisplay800x600At56HzVGA,        800, 600, 0x00380000},        // 56 Hz
  100.         {kDisplay800x600At60HzVGA,        800, 600, 0x003C0000},        // 60 Hz
  101.         {kDisplay800x600At72HzVGA,        800, 600, 0x00480000},        // 72 Hz
  102.         {kDisplay800x600At75HzVGA,        800, 600, 0x004b0000},        // 75 Hz
  103.         {kDisplay832x624At75Hz,            832, 624, 0x004B0000},        // 75 Hz
  104.         {kDisplay1024x768At60HzVGA,        1024, 768, 0x003C0000},        // 60 Hz
  105.         {kDisplay1024x768At72HzVGA,        1024, 768, 0x00480000},        // 72 Hz
  106.         {kDisplay1024x768At75HzVGA,        1024, 768, 0x004B0000},        // 75 Hz
  107.         {kDisplay1024x768At75Hz,        1024, 768, 0x004B0000},        // 75 Hz
  108.         
  109.         {kDisplay1152x870At75Hz,        1152, 870, 0x004B0000},        // 75 Hz
  110.     
  111.         {kDisplay1280x960At75Hz,        1280, 960, 0x004B0000},        // 75 Hz
  112.         {kDisplay1280x1024At75Hz,        1280, 1024, 0x004B0000},    // 75 Hz
  113.  
  114.         {kDisplay256x192At60HzNTSCZoom,    256, 192, 0x003BF080},        // 59.94 Hz
  115.         {kDisplay320x240At50HzPALZoom,    320, 240, 0x00320000},        // 50 Hz
  116.         {kDisplay320x240At60HzNTSCZoom,    320, 240, 0x003BF080},        // 59.94 Hz
  117.         {kDisplay384x288At50HzPALZoom,    384, 288, 0x00320000}        // 50 Hz
  118.     };
  119.  
  120.     for (i = 0; i < kMaxDisplayModeIDs ; i++)
  121.         masterTable[i] = localTable[i];
  122.     
  123.     RegistryEntryIDCopy(regEntryID, &coreData->regEntryID);
  124.     coreData->driverRefNum = refNum;
  125.     coreData->spaceID = spaceID;
  126.     
  127. ErrorExit:
  128.     
  129.     return err;
  130. }
  131.  
  132.  
  133.  
  134. //=====================================================================================================
  135. //
  136. // GraphicsCoreKillPrivateData()
  137. //    Return any resources that the Core has reserved back to the system.
  138. //
  139. //
  140. //=====================================================================================================
  141. void GraphicsCoreKillPrivateData(void)
  142. {
  143.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  144.         
  145.     if (NULL != coreData->gammaTable)
  146.         PoolDeallocate(coreData->gammaTable);
  147.  
  148.     RegistryEntryIDDispose(&coreData->regEntryID);
  149. }
  150.  
  151.  
  152.  
  153. //=====================================================================================================
  154. //
  155. // GraphicsIntialize()
  156. //    This routine is called after getting a 'kInitializeCommand' in DoDriverIO().  This is similar
  157. //    to getting a 'kReplaceCommand', but with subtle differences.  A 'kInitializeCommand' is issued
  158. //    if no version of this driver has been previously loaded, whereas a 'kReplaceCommand' is
  159. //    issued if a previous version of the driver has been loaded.
  160. //
  161. //    This routine must perform the following operations:
  162. //        • Initialize the Core's private data
  163. //        • Initialize the HAL's private data
  164. //        • Install VBL interrupts
  165. //    
  166. //=====================================================================================================
  167. OSErr GraphicsInitialize(DriverRefNum refNum, const RegEntryID* regEntryID, const AddressSpaceID spaceID)
  168. {
  169.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  170.     GDXErr err = kGDXErrUnknownError;            // Assume failure
  171.  
  172.     Boolean alwaysFalse = false;                // Tell HAL to do full initialize, not a replacement.
  173.     
  174.     coreData->replacingDriver = false;            // Doing a kInitializeCommand, not a kReplaceCommand.
  175.     
  176.  
  177.     // In the event that there was a 'CoreReplacementDriverInfo' property in the NameRegistry,
  178.     // delete it to avoid confusion since a 'kInitializeCommand' is occurring.
  179.     (void) GraphicsOSSDeleteProperty(&coreData->regEntryID, "CoreReplacementInfo");
  180.     
  181.     err = GraphicsCoreInitPrivateData(refNum, regEntryID, spaceID);
  182.     if (err)
  183.         goto ErrorExit;
  184.  
  185.     err = GraphicsHALInitPrivateData(regEntryID, &alwaysFalse);
  186.     if (err)
  187.         goto ErrorExit;
  188.         
  189.     err = GraphicsOSSInstallVBLInterrupts(regEntryID);
  190.     if (err)
  191.         goto ErrorExit;
  192.     
  193.     
  194. ErrorExit:
  195.  
  196.     if (err)        
  197.     {
  198.         // Opps...got an internal error and jumped here.  Kill everything.
  199.         GraphicsOSSKillPrivateData();
  200.         GraphicsCoreKillPrivateData();
  201.         GraphicsHALKillPrivateData();
  202.         err = openErr;
  203.     }
  204.  
  205.     return (OSErr) err;    
  206.  
  207. }
  208.  
  209.  
  210.  
  211. //=====================================================================================================
  212. //
  213. // GraphicsReplace()
  214. //    This routine is called after getting a 'kReplaceCommand' in DoDriverIO().  This is similar
  215. //    to getting a 'kInitializeCommand', but with subtle differences.  A 'kInitializeCommand' is issued
  216. //    if no version of this driver has been previously loaded, whereas a 'kReplaceCommand' is
  217. //    issued if a previous version of the driver has been loaded.
  218. //
  219. //    In order to minimize visual artifacts of the new driver 'replacing' the previous one, the Core
  220. //    will attempt to retrieve some information from the NameRegistry which the 'superseded' version
  221. //    of the driver left behind.
  222. //
  223. //    This routine must perform the following operations:
  224. //        • Initialize the Core's private data
  225. //        • Initialize the HAL's private data
  226. //        • Install VBL interrupts
  227. //    
  228. //=====================================================================================================
  229. OSErr GraphicsReplace(DriverRefNum refNum, const RegEntryID *regEntryID, const AddressSpaceID spaceID)
  230. {
  231.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  232.     GDXErr err = kGDXErrUnknownError;                                        // Assume failure
  233.     CoreReplacementDriverInfo replacementDriverInfo;
  234.  
  235.     
  236.     err = GraphicsCoreInitPrivateData(refNum, regEntryID, spaceID);
  237.     if (err)
  238.         goto ErrorExit;
  239.  
  240.     coreData->replacingDriver = true;            // Doing a kReplaceCommand, not a kInitializeCommand.                        
  241.  
  242.  
  243.     // Since a 'replacement' is being attempt, attempt to grab the Core data that was left behind by
  244.     // the 'superseded' driver.  If it isn't found, set 'replacingDriver = false', and operation will
  245.     // continue as if a 'kInitializeCommand' had been issued.
  246.     
  247.     err = GraphicsOSSGetProperty(&coreData->regEntryID, "CoreReplacementInfo",
  248.             &replacementDriverInfo, sizeof(CoreReplacementDriverInfo));
  249.     if (!err)
  250.     {
  251.         // Success!! Found the data left behind by the superseded driver.
  252.         coreData->displayModeID = replacementDriverInfo.displayModeID;
  253.         coreData->depthMode = replacementDriverInfo.depthMode;
  254.         coreData->currentPage = replacementDriverInfo.currentPage;
  255.         coreData->baseAddress = replacementDriverInfo.baseAddress;
  256.     }
  257.     else
  258.     {
  259.         // Opps...didn't find the data, so continue as if an 'kInitializeCommand' had been issued.
  260.         coreData->replacingDriver = false;
  261.     }
  262.  
  263.     // Always try to delete the CoreReplacementDriverInfo in the NameRegistry, so it will not confuse
  264.     // subsequent operations.
  265.     (void) GraphicsOSSDeleteProperty(&coreData->regEntryID, "CoreReplacementInfo");
  266.  
  267.     err = GraphicsHALInitPrivateData(regEntryID, &coreData->replacingDriver);
  268.     if (err)
  269.         goto ErrorExit;
  270.         
  271.     err = GraphicsOSSInstallVBLInterrupts(regEntryID);
  272.     if (err)
  273.         goto ErrorExit;
  274.  
  275.     
  276. ErrorExit:
  277.  
  278.     if (err)
  279.     {
  280.         // Opps...got an internal error and jumped here.  Kill everything.
  281.         GraphicsOSSKillPrivateData();
  282.         GraphicsCoreKillPrivateData();
  283.         GraphicsHALKillPrivateData();
  284.         err = openErr;
  285.     }
  286.  
  287.     return (OSErr) err;    
  288.  
  289. }
  290.  
  291.  
  292.  
  293. //=====================================================================================================
  294. //
  295. // GraphicsOpen()
  296. //    This is called after getting a 'kOpenCommand' in DoDriverIO().
  297. //     This routine must perform the following:
  298. //        • Instruct the HAL to open, putting the hardware in known state.
  299. //        • Create a new interrupt service.
  300. //        • Determine the type of display connected.
  301. //        • Build a default gamma table.
  302. //
  303. //=====================================================================================================
  304. OSErr GraphicsOpen(void)
  305. {
  306.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  307.     GDXErr err = kGDXErrUnknownError;            // Assume failure
  308.  
  309.     DisplayCode displayCode;                    // Connected display
  310.     DisplayCode savedDisplayCode;                // DisplayCode saved from previous boot 
  311.     DisplayModeID displayModeID;                // Saved DisplayModeID from previous boot
  312.     DepthMode depthMode;                        // DepthMode to program hardware with 
  313.     VDGammaRecord defaultGamma;                    // Make GraphicsCoreSetGamma apply gamma table
  314.     GammaTableID gammaTableID;                    // ID of the default gamma table.
  315.     VDSwitchInfoRec switchInfo;                    // Call GraphicsCoreSwitchMode to setup hw
  316.     VDPageInfo pageInfo;                        // Used to gray the screen
  317.     VDFlagRecord flag;                            // Used to turn on interrupts
  318.     Boolean modePossible;                        // Get preferred config, if DisplayCode hasn't changed,
  319.                                                 // make sure there is enough VRAM for the DepthMode 
  320.                                                 // and DisplayModeID.
  321.                                                 
  322.     GraphicsPreferred graphicsPreferred;        // Saved DisplayModeID, DisplayModeID, & DisplayCode
  323.     Boolean savePreferred = false;                // If the preferred configuartion from previous boot 
  324.                                                 // is no longer valid, save the new preferred config
  325.         
  326.  
  327.     // Be safe and init the 'defaultGamma.csGTable = NULL' so that it isn't mistakenly deallocated
  328.     // in the event of an error.
  329.     
  330.     defaultGamma.csGTable = NULL;
  331.     
  332.     // If 'coreData->replacingDriver' is true, that means that the Core got a 'kReplaceCommand'
  333.     // instead of a 'kInitialzeCommand'.  The HAL has already been told that a driver replacement
  334.     // is being attempted. If the HAL managed to get all the information necessary, it would indicate
  335.     // success by leaving 'coreData->replacingDriver = true'.  The HAL has an option to change that
  336.     // variable if it requires that a full initialze take place.
  337.  
  338.     if (coreData->driverOpen)
  339.     {
  340.         err = kGDXErrDriverAlreadyOpen;
  341.         goto ErrorExit;
  342.     }
  343.     
  344.     coreData->gammaTable = NULL;                // No gamma table yet,
  345.     coreData->maxGammaTableSize = 0;            // and likewise, gamma table buffer size is 0
  346.     
  347.     
  348.     
  349.     err = GraphicsHALOpen(coreData->spaceID, coreData->replacingDriver);    // Set hw in a known state
  350.     if (err)
  351.         goto ErrorExit;
  352.  
  353.     err = GraphicsOSSNewInterruptService();
  354.     if (err)
  355.         goto ErrorExit;
  356.     
  357.     // Interrupt routines have been successfully installed.  Turn on interrupts by calling the
  358.     // Core which will turn on interrupts and record the state of interrupts.
  359.     // To enable interrupts, pass a 'csMode' value of 0
  360.     
  361.     flag.csMode = 0;
  362.     err = GraphicsCoreSetInterrupt(&flag);
  363.     if (err)
  364.         goto ErrorExit;
  365.         
  366.     // Read the sense lines and determine what type of monitor is connected.
  367.     err = GraphicsHALDetermineDisplayCode(&displayCode);
  368.     if (err)
  369.         goto ErrorExit;
  370.         
  371.     
  372.     if (kDisplayCodeNoDisplay == displayCode)
  373.     {
  374.         // Exit if no display is connected, but first update the 'preferredConfiguration' to 
  375.         // to show that no monitor is attached.
  376.         
  377.         graphicsPreferred.displayModeID = kDisplay640x480At67Hz;
  378.         graphicsPreferred.depthMode = kDepthMode1;
  379.         graphicsPreferred.displayCode = kDisplayCodeNoDisplay;
  380.         
  381.         (void) GraphicsOSSSetCorePref(&coreData->regEntryID, &graphicsPreferred);
  382.  
  383.         err = kGDXErrNoConnectedMonitor;
  384.         goto ErrorExit;
  385.     }
  386.  
  387.     
  388.     coreData->displayCode = displayCode;                 // Save the DisplayCode in the Core's data
  389.     
  390.     if ((kDisplayCode21InchMono == displayCode) || (kDisplayCodePortraitMono == displayCode))
  391.          coreData->monoOnly = true;
  392.     else
  393.         coreData->monoOnly = false;                
  394.  
  395.     // Find the 'DisplayModeID' and the 'DepthMode' from the previous boot.
  396.  
  397.     err = GraphicsOSSGetCorePref(&coreData->regEntryID, &graphicsPreferred);
  398.     savedDisplayCode = graphicsPreferred.displayCode;
  399.     
  400.     if (err || (savedDisplayCode != displayCode))    
  401.     {
  402.         // Got an error, meaning something is wrong with the saved info, OR the 'DisplayCode' has 
  403.         // changed from the previous boot, so get the best settings for the connected display.
  404.     
  405.         // Set flag to save the preferred configuration since current data stored is inaccurate.
  406.         savePreferred = true;
  407.         
  408.         err    = GraphicsHALGetDefaultDisplayModeID(displayCode, &displayModeID, &depthMode);
  409.     
  410.         if (err)
  411.             goto ErrorExit;
  412.             
  413.     }
  414.     else
  415.     {
  416.         // Successfully retrieved the saved info and 'savedDisplayCode == displayCode'
  417.         if (coreData->replacingDriver && (graphicsPreferred.displayModeID != coreData->displayModeID))
  418.         {
  419.             // Driver replacement is occurring, but the preferred settings don't match those of
  420.             // the driver which was superseded.  Therefore, to avoid excessive visual artifacts,
  421.             // use the settings from the superseded driver.
  422.             
  423.             savePreferred = true;
  424.             displayModeID = coreData->displayModeID;    // DisplayModeID from closed driver
  425.             depthMode = coreData->depthMode;            // DepthMode from closed driver
  426.         }
  427.         else
  428.         {
  429.             // Driver replacement WAS NOT occurring, so use the settings retrieved from the 
  430.             // 'graphicsPreferred' property.
  431.             
  432.             displayModeID = graphicsPreferred.displayModeID;
  433.             depthMode = graphicsPreferred.depthMode;
  434.         }
  435.     }    
  436.  
  437.     if (!coreData->replacingDriver)
  438.         coreData->currentPage = 0;                    // Hard code current page to zero
  439.         
  440.     
  441.     err = GraphicsHALModePossible(displayModeID, depthMode, coreData->currentPage, &modePossible);
  442.  
  443.     if (err || !modePossible)
  444.     {    
  445.         // The HAL did not believe it could drive the specified mode, so try one last time to
  446.         // determine a configuration that the HAL can support for this display.
  447.         
  448.         if (coreData->replacingDriver)
  449.         {
  450.             // Since the HAL can't handle the specified mode, mark 'coreData->replacingDriver' as
  451.             // false, to insure that FULL hardware initialization occurrs.  Additionally, indicate
  452.             // that new preferred settings should be saved.
  453.             
  454.             coreData->replacingDriver = false;
  455.             savePreferred = true;
  456.         }
  457.             
  458.         err    = GraphicsHALGetDefaultDisplayModeID(displayCode, &displayModeID, &depthMode);
  459.         if (err)
  460.             goto ErrorExit;
  461.     }
  462.     
  463.     // Fill in the Core data.
  464.     coreData->displayCode = displayCode;            
  465.     coreData->displayModeID = displayModeID;        
  466.     coreData->depthMode = depthMode;                
  467.     coreData->luminanceMapping = false;                    // Default to no luminance mapping
  468.  
  469.     err = GraphicsHALMapDepthModeToBPP(depthMode, &coreData->bitsPerPixel);
  470.     if (err)
  471.         goto ErrorExit;
  472.  
  473.     
  474.     if (16 <= coreData->bitsPerPixel)
  475.         coreData->directColor = true;            // Direct color when 16, 32 bpp
  476.     else
  477.         coreData->directColor = false;            // Not direct color when < 16 bpp
  478.             
  479.  
  480.     // Attempt to retrieve a default gamma table for the connected display, but if that fails, then
  481.     // apply a linear ramp.
  482.     // Conviently, GraphicsCoreSetGamma will do all the low level stuff, AND IT WILL set
  483.     // coreData->gammaTable appropriately.
  484.  
  485.     err = GraphicsUtilGetDefaultGammaTableID(coreData->displayCode, &gammaTableID);
  486.     
  487.     if (!err)
  488.     {
  489.         // Successfully got the ID of the default gamma table.  So retrieve it and then apply it.
  490.  
  491.         VDRetrieveGammaRec retrieveGamma;
  492.         VDGetGammaListRec getGammaList;
  493.         char gammaTableName[32];                                        // Spot for C-String name
  494.         
  495.         getGammaList.csPreviousGammaTableID = kGammaTableIDSpecific;    // Want info on specific ID
  496.         getGammaList.csGammaTableID = gammaTableID;
  497.         getGammaList.csGammaTableName = (char*)&gammaTableName;
  498.         
  499.         err = GraphicsCoreGetGammaInfoList(&getGammaList);
  500.         if (err)
  501.             goto ErrorExit;
  502.  
  503.         defaultGamma.csGTable = PoolAllocateResident(getGammaList.csGammaTableSize, true);
  504.         if (NULL == defaultGamma.csGTable)
  505.         {
  506.             err = kGDXErrUnableToAllocateGammaTable;
  507.             goto ErrorExit;
  508.         }
  509.         
  510.         retrieveGamma.csGammaTableID = gammaTableID;
  511.         retrieveGamma.csGammaTablePtr = (GammaTbl*)defaultGamma.csGTable;        // Point to the storage
  512.         
  513.         
  514.         err = GraphicsCoreRetrieveGammaTable(&retrieveGamma);
  515.         if (err)
  516.             goto ErrorExit;
  517.                     
  518.         err = GraphicsCoreSetGamma(&defaultGamma);
  519.         if (err)
  520.             goto ErrorExit;
  521.     }
  522.     else
  523.     {
  524.         // Unable to find the ID of a default gamma table, so just apply a linear ramp.
  525.         // Conviently, GraphicsCoreSetGamma will build a default gamma table if we pass it
  526.         // a VDGammaRecord with the csGTable field set to NULL.  AND IT WILL set coreData->gammaTable.
  527.  
  528.         defaultGamma.csGTable = NULL;
  529.         err = GraphicsCoreSetGamma(&defaultGamma);
  530.         
  531.         if (err)                        
  532.             goto ErrorExit;
  533.     }
  534.     
  535.     if (!coreData->replacingDriver)
  536.     {
  537.         // If 'coreData->replacingDriver' was true, it would mean a valid raster and is being driven.
  538.         // However, it currently isn't, so the hardware needs to be programmed to the specified
  539.         // mode and the screen needs to be grayed.  This can be accomplished by calling 
  540.         // GraphicsHALProgramHardware() followed by a call to GraphicsCoreGrayPage().
  541.  
  542.         void *baseAddress;
  543.         Boolean directColor;
  544.         
  545.         err = GraphicsHALProgramHardware(displayModeID, depthMode, 0, &directColor, &baseAddress);
  546.  
  547.         if (err)
  548.             goto ErrorExit;
  549.  
  550.         // Request has been successfully completed, so update the coreData to relfect the current state.
  551.         
  552.         coreData->displayModeID = displayModeID;
  553.         coreData->depthMode = depthMode;
  554.         coreData->currentPage = 0;
  555.         coreData->baseAddress = baseAddress;
  556.         coreData->directColor = directColor;
  557.  
  558.         // Gray the screen
  559.         pageInfo.csPage = 0;                                // Again, hard code for page 0
  560.         err = GraphicsCoreGrayPage(&pageInfo);
  561.         
  562.         if (err)
  563.             goto ErrorExit;
  564.     }
  565.  
  566.     if (savePreferred)
  567.     {
  568.         graphicsPreferred.displayModeID = displayModeID;
  569.         graphicsPreferred.depthMode = depthMode;
  570.         graphicsPreferred.displayCode = displayCode;
  571.         
  572.         err = GraphicsOSSSetCorePref(&coreData->regEntryID, &graphicsPreferred);
  573.         
  574.         err = noErr;    // If we couldn't save the prefs, don't bail out
  575.     }
  576.     
  577.     coreData->driverOpen = true;                        // Driver successfully opened
  578.     
  579. ErrorExit:
  580.  
  581.     if (err)        
  582.     {
  583.         // Opps...got an internal error and jumped here.  Kill everything
  584.         GraphicsOSSKillPrivateData();
  585.         GraphicsCoreKillPrivateData();
  586.         GraphicsHALKillPrivateData();
  587.         err = openErr;
  588.     }
  589.  
  590.     if (NULL != defaultGamma.csGTable)                    // Deallocate default gamma table
  591.         PoolDeallocate(defaultGamma.csGTable);
  592.  
  593.  
  594.     // Always set replacingDriver to false when leaving.  Only a 'kReplaceCommand' should set that flag
  595.     // to true and it should be reset to false after each open.
  596.     
  597.     coreData->replacingDriver = false;
  598.  
  599.     return (OSErr)err;    
  600. }
  601.  
  602.  
  603.  
  604. //=====================================================================================================
  605. //
  606. // GraphicsClose()
  607. //    This is called after getting a 'kCloseCommand' in DoDriverIO().
  608. //     This routine must perform the following:
  609. //        • Disable VBL interrupts (HAL).
  610. //        • Remove the interrupt handler installed by the driver, restoring any vectors it changed during
  611. //          installation (OSS).
  612. //        • Instruct the HAL to close.
  613. // 
  614. //=====================================================================================================
  615. OSErr GraphicsClose(void)
  616. {
  617.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  618.     GDXErr err = kGDXErrUnknownError;                        // Assume failure.
  619.     VDFlagRecord flag;                                        // Used to turn off interrupts.
  620.  
  621.     if (false == coreData->driverOpen)
  622.     {
  623.         err = kGDXErrDriverAlreadyClosed;                    // Shouldn't happen but...
  624.         goto ErrorExit;
  625.     }
  626.     
  627.     flag.csMode = 1;                                        // Disable interrupts.
  628.     err = GraphicsCoreSetInterrupt(&flag);
  629.     if (err)
  630.         goto ErrorExit;
  631.  
  632.     if (NULL != coreData->gammaTable)                        // Deallocate gamma table
  633.     {
  634.         PoolDeallocate(coreData->gammaTable);
  635.         coreData->gammaTable = NULL;
  636.         coreData->maxGammaTableSize = 0;
  637.     }
  638.  
  639.     err = GraphicsOSSDisposeInterruptService();
  640.     if (err)
  641.         goto ErrorExit;
  642.  
  643.     err = GraphicsHALClose(coreData->spaceID);
  644.     if (err)
  645.         goto ErrorExit;
  646.     
  647.     coreData->driverOpen = false;                            // Driver successfully closed.
  648.  
  649. ErrorExit:
  650.  
  651.     return  noErr;                            
  652.  
  653. }
  654.  
  655.  
  656.  
  657. //=====================================================================================================
  658. //
  659. // GraphicsControl()
  660. //    This is called after getting a 'kControlCommand' in DoDriverIO(). This is the bottleneck for
  661. //    control calls.
  662. //
  663. //=====================================================================================================
  664. OSErr GraphicsControl(CntrlParam *pb)
  665. {
  666.  
  667.     OSErr returnErr = noErr;                    // Return REAL external error when not debugging
  668.     GDXErr err = kGDXErrNoError;                // Holds internal errors
  669.     void *genericPtr;
  670.     
  671.     // The 'csParam' field of the 'CntrlParam' stucture is defined as 'short csParam[11]'.  This is
  672.     // meant for 'operation defined parameters.' For the graphics driver, only the first 4 bytes are
  673.     // used.  They are used as a pointer to another structure.
  674.     // To help code readability, the pointer will be extracted as a generic 'void *' and then cast as
  675.     // appropriate.
  676.  
  677.     genericPtr = (void *) *((UInt32 *) &(pb->csParam[0]));
  678.  
  679.     switch (pb->csCode)                // The control call being made
  680.     {
  681.         
  682.            case cscReset:                // Old obsolete call..return a 'controlErr'
  683.             returnErr = controlErr;
  684.             goto ErrorExit;
  685.             break;
  686.             
  687.            case cscKillIO:                // Old obsolete call..do nothing
  688.             err = kGDXErrNoError;
  689.             break;
  690.  
  691.            case cscSetMode:
  692.             err = GraphicsCoreSetMode((VDPageInfo *) genericPtr);
  693.             break;
  694.             
  695.            case cscSetEntries:
  696.             err = GraphicsCoreSetEntries((VDSetEntryRecord *) genericPtr);
  697.             break;
  698.             
  699.            case cscSetGamma:
  700.             err = GraphicsCoreSetGamma((VDGammaRecord *) genericPtr);
  701.             break;
  702.             
  703.            case cscGrayPage:
  704.             err = GraphicsCoreGrayPage((VDPageInfo *) genericPtr);
  705.             break;
  706.             
  707.            case cscSetGray:
  708.             err = GraphicsCoreSetGray((VDGrayRecord *) genericPtr);
  709.             break;
  710.             
  711.            case cscSetInterrupt:
  712.             err = GraphicsCoreSetInterrupt((VDFlagRecord *) genericPtr);
  713.             break;
  714.             
  715.            case cscDirectSetEntries:
  716.             err = GraphicsCoreDirectSetEntries((VDSetEntryRecord *) genericPtr);
  717.             break;
  718.             
  719.            case cscSetDefaultMode:            // Old call that doesn't work in Slot Mgr Independent (SMI) API
  720.             returnErr = controlErr;
  721.             goto ErrorExit;
  722.             break;
  723.             
  724.            case cscSwitchMode:
  725.             err = GraphicsCoreSwitchMode((VDSwitchInfoRec *) genericPtr);
  726.             break;
  727.             
  728.            case cscSetSync:
  729.             err = GraphicsCoreSetSync((VDSyncInfoRec *) genericPtr);
  730.             break;
  731.         
  732.         case cscSavePreferredConfiguration:
  733.             err = GraphicsCoreSetPreferredConfiguration((VDSwitchInfoRec *) genericPtr);
  734.             break;
  735.  
  736.            case cscSetHardwareCursor:
  737.             err = GraphicsCoreSetHardwareCursor((VDSetHardwareCursorRec *) genericPtr);
  738.             break;
  739.  
  740.            case cscDrawHardwareCursor:
  741.             err = GraphicsCoreDrawHardwareCursor((VDDrawHardwareCursorRec *) genericPtr);
  742.             break;
  743.  
  744.            case cscSetPowerState:
  745.             err = GraphicsCoreSetPowerState((VDPowerStateRec *) genericPtr);
  746.             break;
  747.  
  748.         default:                            // This will return the appropriate error code
  749.             returnErr = GraphicsHALPrivateControl(genericPtr, pb->csCode);
  750.             goto ErrorExit;
  751.     }
  752.     
  753.  
  754.     if (err)
  755.         returnErr = paramErr;
  756.     else
  757.         returnErr = noErr;
  758.     
  759. ErrorExit:
  760.     
  761.     return returnErr;
  762.  
  763. }    
  764.  
  765.  
  766. //=====================================================================================================
  767. //
  768. // GraphicsStatus()
  769. //    This is called after getting a 'kStatusCommand' in DoDriverIO(). This is the bottleneck for
  770. //    status calls.
  771. // 
  772. //=====================================================================================================
  773. OSErr GraphicsStatus(CntrlParam    *pb)
  774. {
  775.  
  776.     OSErr returnErr = noErr;                    // return REAL external error when not debugging
  777.     GDXErr err = kGDXErrNoError;                // holds internal errors
  778.     DisplayCode unusedDisplayCode;                // Get Preferred returns the display type also for
  779.                                                 // internal use
  780.     void *genericPtr;
  781.     
  782.     // The 'csParam' field of the 'CntrlParam' stucture is defined as 'short csParam[11]'.  This is
  783.     // meant for 'operation defined parameters.' For the graphics driver, only the first 4 bytes are
  784.     // used.  They are used as a pointer to another structure.
  785.     // To help code readability, the pointer will be extracted as a generic 'void *' and then cast as
  786.     // appropriate.
  787.  
  788.     genericPtr = (void *) *((UInt32 *) &(pb->csParam[0]));
  789.     
  790.     switch (pb->csCode)                    // The status call being made
  791.     {
  792.         
  793.            case cscGetMode:
  794.             err = GraphicsCoreGetMode((VDPageInfo *) genericPtr);
  795.             break;
  796.             
  797.            case cscGetEntries:
  798.             err = GraphicsCoreGetEntries((VDSetEntryRecord *) genericPtr);
  799.             break;
  800.             
  801.            case cscGetPages:
  802.             err = GraphicsCoreGetPages((VDPageInfo *) genericPtr);
  803.             break;
  804.             
  805.         case cscGetBaseAddr:
  806.             err = GraphicsCoreGetBaseAddress((VDPageInfo *) genericPtr);
  807.             break;
  808.             
  809.            case cscGetGray:
  810.             err = GraphicsCoreGetGray((VDGrayRecord *) genericPtr);
  811.             break;
  812.             
  813.            case cscGetInterrupt:
  814.             err = GraphicsCoreGetInterrupt((VDFlagRecord *) genericPtr);
  815.             break;
  816.             
  817.            case cscGetGamma:
  818.             err = GraphicsCoreGetGamma((VDGammaRecord *) genericPtr);
  819.             break;
  820.             
  821.            case cscGetDefaultMode:            // Old call that doesn't work in Slot Mgr Independent (SMI) API
  822.             err = kGDXErrUnknownError;
  823.             break;
  824.             
  825.            case cscGetCurMode:
  826.             err = GraphicsCoreGetCurrentMode((VDSwitchInfoRec *) genericPtr);
  827.             break;
  828.                         
  829.            case cscGetSync:
  830.             err = GraphicsCoreGetSync((VDSyncInfoRec *) genericPtr);
  831.             break;
  832.                         
  833.            case cscGetConnection:
  834.             err = GraphicsCoreGetConnection((VDDisplayConnectInfoRec *) genericPtr);
  835.             break;
  836.                         
  837.            case cscGetModeTiming:
  838.             err = GraphicsCoreGetModeTiming((VDTimingInfoRec *) genericPtr);
  839.             break;
  840.                         
  841.         case cscGetPreferredConfiguration:
  842.             err = GraphicsCoreGetPreferredConfiguration((VDSwitchInfoRec *) genericPtr);
  843.             break;
  844.  
  845.         case cscGetNextResolution:
  846.             err = GraphicsCoreGetNextResolution((VDResolutionInfoRec *) genericPtr);
  847.             break;
  848.  
  849.            case cscGetVideoParameters:
  850.             err = GraphicsCoreGetVideoParams((VDVideoParametersInfoRec *) genericPtr);
  851.             break;
  852.        
  853.            case cscGetGammaInfoList:
  854.             err = GraphicsCoreGetGammaInfoList((VDGetGammaListRec *) genericPtr);
  855.             break;
  856.  
  857.            case cscRetrieveGammaTable:
  858.             err = GraphicsCoreRetrieveGammaTable((VDRetrieveGammaRec *) genericPtr);
  859.             break;
  860.  
  861.         case cscSupportsHardwareCursor:
  862.             err = GraphicsCoreSupportsHardwareCursor((VDSupportsHardwareCursorRec *) genericPtr);
  863.             break;
  864.  
  865.         case cscGetHardwareCursorDrawState:
  866.             err = GraphicsCoreGetHardwareCursorDrawState((VDHardwareCursorDrawStateRec *) genericPtr);
  867.             break;
  868.  
  869.            case cscGetPowerState:
  870.             err = GraphicsCoreGetPowerState((VDPowerStateRec *) genericPtr);
  871.             break;
  872.             
  873.         default:                            // This will return the appropriate error code
  874.             returnErr = GraphicsHALPrivateStatus(genericPtr, pb->csCode);
  875.             goto ErrorExit;
  876.             
  877.     }
  878.  
  879.     if (err)
  880.         returnErr = paramErr;
  881.     else
  882.         returnErr = noErr;
  883.     
  884. ErrorExit:
  885.     
  886.     return returnErr;
  887. }
  888.  
  889.  
  890.  
  891. //=====================================================================================================
  892. //
  893. // GraphicsFinalize()
  894. //    This routine is called after getting a 'kFinalizeCommand' in DoDriverIO().  This is similar
  895. //    to getting a 'kSupersededCommand', but with subtle differences.  A 'kFinalizeCommand' is issued
  896. //    if the driver is going away for good, whereas as a 'kSupersededCommand' is issued if the driver
  897. //    will be replaced with a later, greater version.
  898. //    This will do the following:
  899. //        • Instruct the HAL to terminate, turning off its raster
  900. //        • Instruct the Core to kill its private data
  901. //        • Instruct the HAL to kill its private data
  902. //        (NOTE: the OSS already killed its private data, when it recieved the 'kFinalizeCommand')
  903. //
  904. //=====================================================================================================
  905. OSErr GraphicsFinalize(DriverRefNum refNum, const RegEntryID* regEntryID)
  906. {
  907.     // Release LOCAL Storage
  908.         
  909.     (void) GraphicsHALTerminate(false);        // The 'false' indicates this is a 'kFinalizeCommand', and
  910.                                             // not a 'kSupersededCommand'.
  911.     GraphicsCoreKillPrivateData();
  912.     GraphicsHALKillPrivateData();
  913.  
  914.     return noErr;
  915.  
  916. }
  917.  
  918.  
  919.  
  920. //=====================================================================================================
  921. //
  922. // GraphicsSupersede()
  923. //    This routine is called after getting a 'kSupersededCommand' in DoDriverIO().  This is similar
  924. //    to getting a 'kFinalizeCommand', but with subtle differences.  A 'kFinalizeCommand' is issued
  925. //    if the driver is going away for good, whereas as a 'kSupersededCommand' is issued if the driver
  926. //    will be replaced with a later, greater version.
  927. //    This will do the following:
  928. //        • Save key portions of the Core data, so that the replacement driver can attempt to come
  929. //          come up in the same state.
  930. //        • Instruct the HAL to terminate, but leave its raster on.
  931. //        • Instruct the Core to kill its private data
  932. //        • Instruct the HAL to kill its private data
  933. //        (NOTE: the OSS already killed its private data, when it recieved the 'kSupersededCommand')
  934. //    
  935. //=====================================================================================================
  936. OSErr GraphicsSupersede(DriverRefNum refNum, const RegEntryID* regEntryID)
  937. {
  938.     GraphicsCoreData *coreData = GraphicsCoreGetCoreData();
  939.     CoreReplacementDriverInfo replacementDriverInfo;
  940.  
  941.     replacementDriverInfo.displayModeID = coreData->displayModeID;
  942.     replacementDriverInfo.depthMode = coreData->depthMode;
  943.     replacementDriverInfo.currentPage = coreData->currentPage;
  944.     replacementDriverInfo.baseAddress = coreData->baseAddress;
  945.  
  946.     
  947.     (void) GraphicsOSSSaveProperty(&coreData->regEntryID, "CoreReplacementInfo",
  948.             &replacementDriverInfo, sizeof(CoreReplacementDriverInfo), kOSSPropertyVolatile);
  949.         
  950.     (void) GraphicsHALTerminate(true);        // The 'true' indicates this is a 'kSupersededCommand', and
  951.                                             // not a 'kFinalizeCommand'.
  952.     GraphicsCoreKillPrivateData();
  953.     GraphicsHALKillPrivateData();
  954.  
  955.     return noErr;
  956.  
  957. }
  958.